const initProducts = function (config) {
  return fetch(Utils.stringFormat(config.activityInfoUrl, {ids: config.skuIds.join(',')}))
    .then((response) => {
      return response.json();
    })
    .then((json) => {
      let products = {};
      json.skuRushBuyInfoList.forEach((product) => {
        let skuId = product.skuId;
        if (config.startTime) {
          product.startTime = config.startTime;
        }
        products[skuId] = product;
      });

      return products;
    });
};

const createOrderParams = function (product, user) {
  let timestamp = product.startTime;
  return {
    'nowTime': (new Date(timestamp + 100)).customFormat('yyyy-M-d h:m:s'),
    'callback': `callback${timestamp}`,
    'skuId': product.skuId,
    'skuIds': product.skuId,
    'activityId': product.activityId,
    'uid': user.uid,
    'user': user.user,
    'name': user.name,
    'ts': user.ts,
    'valid': '1',
    'sign': user.sign,
    'cid': 'null',
    'wi': 'null',
    'ticket': user.ticket,
    'hasphone': user.hasphone,
    'hasmail': user.hasmail,
    'logintype': user.logintype,
    't': timestamp
   };
};

const createBuyParams = function (user, product, orderSign) {
  return {
    uid: user.uid,
    skuIds: product.skuId,
    quantity: 1,
    orderSign: orderSign,
    activityId: product.activityId,
    streetId: '28033',
    street: '岳麓街道',
    districtId: '4937',
    district: '岳麓区',
    cityId: '4936',
    city: '长沙',
    provinceId: '4935',
    province: '湖南',
    consignee: '陈进',
    address: '中电软件园',
    mobile: '18670366212',
    phone: '',
    zipCode: '',
    custName: user.name,
    titleType: 50,
    invoiceTitle: '个人',
    taxpayerIdentityNum: '',
    orderSource: 1,
    activityUid: user.uid,
    sign: user.sign,
    nickName: user.name,
    ts: user.ts,
    valid: 1,
    ticket: user.ticket,
    hasphone: user.hasphone,
    hasmail: user.hasmail,
    logintype: user.logintype
  };
};

const run = async function (config, user, product) {
  let queue = await fetch(Utils.stringFormat(config.queueUrl, {uid: user.uid, qid: product.qids}))
    .then((response) => {
      return response.text();
    })
    .then((text) => {
      let json = JSON.parse(Utils.extractJsonp(text));
      return json;
    });

  let cookies = {};
  cookies[`isqueue-${product.activityId}-${user.uid}`] = queue.isqueue;
  cookies[`queueSign-${product.activityId}-${user.uid}`] = queue.queueSign;
  cookies = Utils.cookieStringify(cookies);

  let url = '';
  let orderParams = createOrderParams(product, user);
  orderParams = Utils.queryStringify(orderParams);
  url = Utils.stringFormat(config.orderUrl, {query: orderParams});

  let modifier = config.users[user.uid] && config.users[user.uid].modifier || 0;
  let timestamp = Date.now();
  let interval = product.startTime - timestamp + modifier;

  setTimeout(() => {
    let runAt = Date.now();
    fetch(url, {
      headers: {
        'X-Cookie': cookies
      }
    }).then((response) => {
      return response.text();
    })
    .then((text) => {
      console.log(`Run at: ${runAt}, User: ${user.name}`, text);
    });
  }, interval);
};

const updateUsers = function (user) {
  const storageKey = 'users';
  let users = {};
  try {
    users = JSON.parse(localStorage.getItem(storageKey) || '{}');
  } catch (e) {
    users = {};
  }

  user = user || {};
  if (user.uid) {
    users[user.uid] = user;
  }

  localStorage.setItem(storageKey, JSON.stringify(users));
  return users;
};

const injectUser = function (config, products, user) {
  user = user || {};

  if (!user.uid) {
    return;
  }

  console.log(`Register user:  ${user.name}`);
  if (user.sessionTimer) {
    clearInterval(user.sessionTimer);
  }

  const refresh = async function (user) {
    if (!user.euid) {
      return;
    }

    // Refresh session.
    await fetch(
      config.refreshSessionUrl,
      {
        'headers': {
          'X-Cookie': Utils.cookieStringify({euid: user.euid}),
        }
      }
    )
    .then((response) => {
      return response.json();
    })
    .then((json) => {
        if (!json.success) {
          user.euid = null;
          if (user.sessionTimer) {
            clearInterval(user.sessionTimer);
          }
          console.log(`${user.name} session timeout.`);
        }

        updateUsers(user);
    });
  };

  // user.sessionTimer = setInterval(() => {
  //   refresh(user);
  // }, config.refreshSessionInterval * 60 * 1000);

  // Need fixed.
  config.selectedSkus.forEach((id) => {
    run(config, user, products[id]);
  });
};

const registerEvents = function (config, products) {
  chrome.webRequest.onBeforeSendHeaders.addListener(
    (details) => {
      let headers = details.requestHeaders.reduce((result, element) => {
        if (element.name.toLowerCase() === 'x-cookie') {
          result.push({
            name: 'Cookie',
            value: element.value,
          });
        } else {
          result.push(element);
        }

        return result;
      }, []);

      return {requestHeaders: headers};
    },
    {
      urls: config.cookieFilterUrls,
    },
    ['requestHeaders', 'blocking']
  );

  // chrome.webRequest.onBeforeRequest.addListener(
  //   (details) => {
  //     return {
  //       redirectUrl: 'https://gitee.com/jin-chen/rush/raw/master/js/hw/acctguard-20170919.min.js'
  //     };
  //   },
  //   {
  //     urls: ['https://hwid1.vmallres.com/CAS/up/rss_14/js/pc_rss/secrisk/acctguard-20170919.min.js*']
  //   },
  //   ['blocking']
  // );

  // chrome.webRequest.onBeforeSendHeaders.addListener(
  //   (details) => {
  //     console.log(details.url);
  //     details.requestHeaders.forEach((element) => {
  //       if (element.name.toLowerCase() === 'cookie') {
  //         console.log(Utils.cookieParse(element.value));
  //       }
  //     });
  //   },
  //   {
  //     urls: config.productPageUrl
  //   },
  //   ['requestHeaders']
  // );

  // chrome.webRequest.onHeadersReceived.addListener(
  // (details) => {
  //     var log = {
  //       method: details.method,
  //       url: details.url,
  //       cookies: []
  //     };
  //     details.responseHeaders.forEach((element) => {
  //       if (element.name.toLowerCase().indexOf('cookie') != -1) {
  //         log.cookies.push(element.value);
  //       }
  //     });
  //     if (log.cookies.length > 0) {
  //       console.log(log.cookies.length, log);
  //     }
  //   },
  //   {
  //     urls: config.setCookieFilterUrls,
  //   },
  //   ['responseHeaders']
  // );

  // Access-Control-Allow-Origin
  chrome.webRequest.onHeadersReceived.addListener(
    (details) => {
      details.responseHeaders.push({
        name: 'Access-Control-Allow-Origin',
        value: '*'
      });

      return {responseHeaders: details.responseHeaders};
    },
    {
      urls: [
        'https://hwid1.vmall.com/Captcha/chkPreprocess',
        'https://hwid1.vmall.com/CAS/ajaxHandler/dev',
      ],
    },
    ['responseHeaders', 'blocking']
  );

  chrome.webRequest.onHeadersReceived.addListener(
    (details) => {
      let user = {};
      details.responseHeaders.forEach((header) => {
        if (header.name.toLowerCase() === 'set-cookie') {
          const [str] = header.value.split(/\s*;\s*/);
          const [k, v] = str.split(/\s*=\s*/);
          user[decodeURIComponent(k)] = decodeURIComponent(v);
        }
      });

      injectUser(config, products, user);
      return {responseHeaders: details.responseHeaders};
    },
    {
      urls: config.loginFilterUrls,
    },
    ['responseHeaders']
  );
};

const init = async function () {
  const config = {
    refreshSessionUrl: 'https://www.vmall.com/member/accountInfo.json',
    activityInfoUrl: 'https://buy.vmall.com/getSkuRushbuyInfo.json?skuIds={ids}',
    queueUrl: 'https://yy.vmall.com/ivy/isqueue.jsp?uid={uid}&qid={qid}',
    orderUrl: 'https://ord01.vmall.com/order/pwm86t/createOrder.do?{query}',
    buyUrl: 'https://buy.vmall.com/order/create.json?duid={uid}',
    refreshSessionInterval: 5,
    skuIds: ['81139976', '209635140', '834134284', '838944902'],
    selectedSkus: ['838944902'],
    // startTime: Date.parse('2017-12-21 10:28:00'),
    cookieFilterUrls: [
      'https://www.vmall.com/member/accountInfo.json',
      'https://yy.vmall.com/ivy/isqueue.jsp*',
      'https://ord01.vmall.com/order/pwm86t/createOrder.do*',
    ],
    productPageUrl: [
      'https://www.vmall.com/product/*.html',
    ],
    setCookieFilterUrls: [
      'https://*.vmall.com/*',
    ],
    loginFilterUrls: [
      'https://www.vmall.com/account/acaslogin*',
    ],
    users: {
      '260086000246327122': {
          'uid': '260086000246327122',
          'email': 'mole.chen@qq.com',
          'modifier': 100
      },
      '260086000246911268': {
          'uid': '260086000246911268',
          'email': 'mole.jin@better-debt.com',
          'modifier': 120
      },
      '260086000246911342': {
          'uid': '260086000246911342',
          'email': 'jim.jin@better-debt.com',
          'modifier': 150
      },
      '260086000246911382': {
          'uid': '260086000246911382',
          'email': 'tom.jin@better-debt.com',
          'modifier': 180
      },
      '260086000246952434': {
          'uid': '260086000246952434',
          'email': 'one.jin@better-debt.com',
          'modifier': 200
      },
      '260086000246952449': {
          'uid': '260086000246952449',
          'email': 'two.jin@better-debt.com',
          'modifier': 250
      },
      '260086000246952461': {
          'uid': '260086000246952461',
          'email': 'three.jin@better-debt.com',
          'modifier': 300
      },
      '260086000246952527': {
          'uid': '260086000246952527',
          'email': 'four.jin@better-debt.com',
          'modifier': 400
      },
      '260086000246952538': {
          'uid': '260086000246952538',
          'email': 'five.jin@better-debt.com',
          'modifier': 420
      },
      '260086000246952672': {
          'uid': '260086000246952672',
          'email': 'six.jin@better-debt.com',
          'modifier': 450
      },
      '260086000246952709': {
          'uid': '260086000246952709',
          'email': 'seven.jin@better-debt.com',
          'modifier': 500
      },
      '260086000246952761': {
          'uid': '260086000246952761',
          'email': 'eight.jin@better-debt.com',
          'modifier': 550
      },
      '260086000246952785': {
          'uid': '260086000246952785',
          'email': 'nine.jin@better-debt.com',
          'modifier': 600
      },
      '260086000246952831': {
          'uid': '260086000246952831',
          'email': 'ten.jin@better-debt.com',
          'modifier': 1000
      }
    }
  };

  // Register events.
  let products = await initProducts(config);
  registerEvents(config, products);

  // For debug
  let users = updateUsers();
  Object.keys(users).forEach((id) => {
    injectUser(config, products, users[id]);
  });
};

init();

